package {
	import com.adobe.serialization.json.SimpleClass;
	import com.rational.serialization.json.JSON;
	import flash.utils.ByteArray;
	import flash.utils.describeType;
	import mx.core.Application;
	import mx.controls.Alert;
	import mx.controls.TextArea;
	import org.flexunit.Assert;
	public class SimpleTest {
		private var show:Function = Alert.show;
		[Test(description="This tests an empty object")]
		public function emptyObject():void {
			var object:Object = JSON.decode("{}");
			Assert.assertTrue(object is Object);
		}
		[Test(description="This tests an empty array")]
		public function emptyArray():void {
			var array:Array = JSON.decode("[]");
			Assert.assertTrue(array is Array);
			Assert.assertEquals(0, array.length);
		}
		[Test(description="This tests a true array")]
		public function trueArray():void {
			var array:Array = JSON.decode("[true,true,true]");
			Assert.assertTrue(array is Array);
			Assert.assertEquals(3, array.length);
			for each (var element:Boolean in array) {
				Assert.assertTrue(element is Boolean);
				Assert.assertTrue(element);
			}
		}
		[Test(description="This tests a false array")]
		public function falseArray():void {
			var array:Array = JSON.decode("[ false, false, false, false, false ]");
			Assert.assertTrue(array is Array);
			Assert.assertEquals(5, array.length);
			for each (var element:Boolean in array) {
				Assert.assertTrue(element is Boolean);
				Assert.assertFalse(element);
			}
		}
		[Test(description="This tests a null array")]
		public function nullArray():void {
			var array:Array = JSON.decode("[\nnull\n,\tnull\t, null ,null]");
			Assert.assertTrue(array is Array);
			Assert.assertEquals(4, array.length);
			for each (var element:* in array) {
				Assert.assertStrictlyEquals(null, element);
			}
		}
		[Test(description="This tests a simple object")]
		public function simpleObject():void {
			var object:Object = JSON.decode("{\"intValue\":42}");
			Assert.assertTrue(object.hasOwnProperty("intValue"));
			Assert.assertEquals(42, object.intValue);
		}
		[Test(description="This tests true")]
		public function trueObject():void {
			var boolean:Boolean = JSON.decode("true");
			Assert.assertTrue(boolean is Boolean);
			Assert.assertTrue(boolean);
		}
		[Test(description="This tests false")]
		public function falseObject():void {
			var boolean:Boolean = JSON.decode("false");
			Assert.assertTrue(boolean is Boolean);
			Assert.assertFalse(boolean);
		}
		[Test(description="This tests a number")]
		public function numberObject():void {
			var number:Number = JSON.decode("1");
			Assert.assertTrue(number is Number);
			Assert.assertEquals(1, number);
			number = JSON.decode("-2");
			Assert.assertTrue(number is Number);
			Assert.assertEquals(-2, number);
		}
		[Test(description="This tests a string")]
		public function stringObject():void {
			var string:String = JSON.decode("\"hello, world!\"");
			Assert.assertTrue(string is String);
			Assert.assertEquals("hello, world!", string);
		}
		[Test(description="This tests properties that begin with t")]
		public function propertyStartsWithT():void {
			var object:Object = JSON.decode(" { \"team\": 1 } ");
			Assert.assertTrue(object.hasOwnProperty("team"));
			Assert.assertEquals(1, object.team);
		}
		[Test(description="This tests true property value parsing")]
		public function trueProperty():void {
			var object:Object = JSON.decode(" { \"team\": true } ");
			Assert.assertTrue(object.hasOwnProperty("team"));
			Assert.assertEquals(true, object.team);
		}
		[Test(description="Test JSONTest.as object failure")]
		public function jsonTestObjectFailure():void {
			var object:Object = JSON.decode(" { \"test\": true, \"test2\": -12356732.12 } ");
			Assert.assertTrue(object.hasOwnProperty("test"));
		}
		[Test(description="Test JSONTest.as array failure")]
		public function jsonTestArrayFailure():void {
			var array:Array = JSON.decode(" [ null, true, false, 100, -100, \"test\", { \"foo\": \"bar\" } ] ");
			Assert.assertTrue(array is Array);
			Assert.assertEquals(7, array.length);
		}
		[Test(description="Test JSONTest.as unicode failure")]
		public function jsonTestUnicodeFailure():void {
			var string:String = JSON.decode("\"\\u0061\"");
			Assert.assertTrue(string is String);
			Assert.assertEquals("a", string);
		}
		[Test]
		public function testDecodePositiveFloat():void {
			var n:Number = JSON.decode( "12.987324" ) as Number;
			Assert.assertEquals( n, 12.987324 );
    }
		[Test]
		public function testDecodeWhiteSpace():void {
			var n:Number = JSON.decode( " 1 " );
      Assert.assertEquals( 1, n );
		}
		[Test]
		public function testDecodeScientificRegularExponent():void {
			var n:Number = JSON.decode( "6.02e2" ) as Number;
			Assert.assertEquals( n, 602 );
				
			n = JSON.decode( "-2e10" );                     
			Assert.assertEquals( n, -20000000000 ); 
			Assert.assertEquals( n, -2 * Math.pow( 10, 10 ) );
		}
		[Test]
		public function testDecodeScientificPositiveExponent():void {
			var n:Number = JSON.decode( "2E+9" ) as Number;
			Assert.assertEquals( n, 2 * Math.pow( 10, 9 ) );
				
			n = JSON.decode( "-2.2E+23" ) as Number;
			Assert.assertEquals( n, -2.2 * Math.pow( 10, 23 ) );
		}
		[Test(description="This tests for proper date handling")]
		public function dates():void {
			var d:Date = JSON.decode('["time", 123]');
			Assert.assertTrue(d is Date);
			Assert.assertEquals(123, d.time);

			var a:Array = JSON.decode('["time", 123, "hi"]');
			Assert.assertTrue(a is Array);
			Assert.assertEquals(3, a.length);
			Assert.assertEquals("time", a[0]);
			Assert.assertEquals(123, a[1]);
			Assert.assertEquals("hi", a[2]);
		}
		[Test(description="This tests for proper typing")]
		public function simpleClass():void {
			var s1:SimpleClass = new SimpleClass();
			s1.publicVar1 = 5;
			s1.publicVar2 = 18;
			var s2:SimpleClass = JSON.decode(JSON.encode(s1), SimpleClass);
			Assert.assertTrue(s2 is SimpleClass);
		}
		[Test]
		public function testDecodeStringWithControlCharacters():void {
			var i:int, length:int, j:int;			
			for (i = 0x00; i <= 0x1F; i++) {
				var string:String = "control char " + i + ": <" + String.fromCharCode( i ) + ">.";
				var actual:Array = JSON.decode( "[\"" + string + "\"]")
				var stringba:ByteArray = new ByteArray(), actualba:ByteArray = new ByteArray();
				stringba.writeUTFBytes(string);
				actualba.writeUTFBytes(actual[0]);
				Assert.assertEquals("position", stringba.position, actualba.position);
				length = stringba.position;
				stringba.position = 0;
				actualba.position = 0;
				for (j = 0; j < length; j++) {
					var position:int = stringba.position;
					var stringByte:String = stringba.readUTFBytes(1);
					Assert.assertEquals("stringba position", position + 1, stringba.position);
					position = actualba.position;
					var actualByte:String = actualba.readUTFBytes(1);
					Assert.assertEquals("actualba position", position + 1, actualba.position);
					Assert.assertEquals("string[" + j + "](" + stringByte + ") == actual[" + j + "](" + actualByte + ")", stringByte, actualByte);
				}
				Assert.assertEquals(string.length, actual[0].length); 
				Assert.assertEquals(string, actual[0]);
			}
		}
		[Test(description="This tests embedded null characters in strings")]
		public function nullCharacter():void {
			const string:String = '["beginning \\u0000 end"]',
				expected:String = "beginning " + String.fromCharCode(0) + " end";
			var actual:* = JSON.decode(string);
			Assert.assertTrue(actual is Array);
			Assert.assertEquals(1, actual.length);
			//Assert.assertEquals(expected.length, actual[0].length);
			Assert.assertEquals(expected, actual[0]);
		}
		[Test(description="This tests extended ASCII character encoding as UTF")]
		public function extendedASCII():void {
			const expected:String = String.fromCharCode(0xc2, 0xa7);
			const string:String = '"' + expected + '"';
			var actual:* = JSON.decode(string);
			Assert.assertEquals(expected, actual);
		}
	}
}